#include "../StdInc.h"

namespace GSTrader
{
	namespace Indicator
	{
		CIndicatorManager::CIndicatorManager(CFrameworkBase* pFramework) : m_pFramework(pFramework)
		{
		}


		CIndicatorManager::~CIndicatorManager()
		{
			for (auto p : m_mapIndicator)
			{
				_delete(p.second)
			}

			m_mapIndicator.clear();

			for (auto it : m_mapIndicatorInstance)
			{
				vector<CIndicator*>& vIndicator = it.second;
				for (auto p : vIndicator)
				{
					_delete(p)
				}

				vIndicator.clear();
			}

			m_mapIndicatorInstance.clear();
		}

		void CIndicatorManager::Init()
		{
			m_mapIndicator["MA"] = new MA;
			m_mapIndicator["VOL"] = new VOL;
			m_mapIndicator["MACD"] = new MACD;
			m_mapIndicator["BOLL"] = new BOLL;
			m_mapIndicator["KDJ"] = new KDJ;
			m_mapIndicator["RSI"] = new RSI;
		}

		bool CIndicatorManager::AddNewIndicator(string strIndicatorName, CIndicator* pIndicator)
		{
			if (pIndicator == NULL || strIndicatorName.empty())
				return false;

			CIndicator* pExist = GetIndicator(strIndicatorName);
			if (pExist)
				return false;

			if (pIndicator->m_strIndicatorName.empty())
			{
				pIndicator->m_strIndicatorName = strIndicatorName;
			}

			m_mapIndicator[strIndicatorName] = pIndicator;
			return true;
		}

		CIndicator* CIndicatorManager::CreateIndicatorInstance(string strIndicatorName)
		{
			if (strIndicatorName.empty())
				return NULL;

			CIndicator* pIndicator = GetIndicator(strIndicatorName);
			if (pIndicator)
			{
				CIndicator* pNew =  pIndicator->CreateInstance();
				if (pNew)
				{
					auto it = m_mapIndicatorInstance.find(strIndicatorName);
					if (it == m_mapIndicatorInstance.end())
					{
						m_mapIndicatorInstance[strIndicatorName] = vector<CIndicator*>();
						it = m_mapIndicatorInstance.find(strIndicatorName);
					}

					vector<CIndicator*>& vIndicator = it->second;
					vIndicator.push_back(pNew);
					return pNew;
				}
			}

			return NULL;
		}

		bool CIndicatorManager::RemoveIndicatorInstance(CIndicator* pIndicator)
		{
			if (pIndicator == NULL || pIndicator->m_strIndicatorName.empty())
			{
				assert(false);
				return false;
			}

			auto it = m_mapIndicatorInstance.find(pIndicator->m_strIndicatorName);
			if (it == m_mapIndicatorInstance.end())
			{
				return false;
			}

			vector<CIndicator*>& vIndicator = it->second;
			for (size_t x = 0; x < vIndicator.size(); x++)
			{
				if (vIndicator[x] == pIndicator)
				{
					vIndicator.erase(vIndicator.begin() + x);
					_delete(pIndicator)
					return true;
				}
			}

			return false;
		}

		CIndicator* CIndicatorManager::GetIndicator(string strIndicatorName)
		{
			auto it = m_mapIndicator.find(strIndicatorName);
			if (it != m_mapIndicator.end())
				return it->second;

			return NULL;
		}
	}
}